home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / tex / tools / dvi_300b / treiber / sources / 9_nadel.c next >
C/C++ Source or Header  |  1995-11-25  |  10KB  |  235 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3.  
  4. #include <tos.h>
  5.  
  6. #include "portab.h"
  7. #include "treiber.h"
  8.  
  9. /***************************/
  10. /* Version 1.0 von 10.2.93 */
  11. /* Markus Pristovsek       */
  12. /* Nur 240*216 dpi         */
  13. /***************************/
  14. /* Version 1.1 von 1.3.93  */
  15. /* Alle Auflösungen, d.h.  */
  16. /* hor.: 240,120,90,80,72  */
  17. /* ver.: 216,144,72 dpi    */
  18. /***************************/
  19. /* Version 1.2 von 23.8.93 */
  20. /* Drehen per Assembler    */
  21. /***************************/
  22. /* Version 1.3 von 7.10.95 */
  23. /* Quer- und Hochkant in   */
  24. /* einem Treibermodul      */
  25. /***************************/
  26.  
  27. #define BITS_PER_CHAR    20    /* Elite-Dichte! */
  28. #define COMPRESSION 2    /* Von 2 bis 0 (so lassen) */
  29. #define MAX_DPI    240L
  30. #define WEITE 1920     /* Für DINA3 vergrößern! */
  31. #define HOEHE -1    /* Unbeschränkt */
  32.  
  33. static UBYTE    dpi_modus[]={ 240, 3, 120, 1, 90, 6, 72, 5 };
  34. static UBYTE    dpi_vmodus[]={ 216, 3, 144, 2, 72, 1 };
  35. static UBYTE    *INIT="\33@\33M\33\63\1\15";
  36. static UBYTE    *V_STEP="\0\33J\0";
  37.  
  38. LONG    max_puffer_laenge = 1;    /* Nur Semaphore bekommen (=<128)! */
  39.  
  40.  
  41. /********************************************************************/
  42.  
  43. /* Komprimiert eine Zeile */
  44. void write_compressed( WORD th, UBYTE *tmp, LONG len, long bpc )
  45. {
  46.     LONG    i, j;
  47.  
  48.     if(  len>0  )
  49.     {
  50. #if COMPRESSION==2
  51.         /* Schneidet nur links und rechts ab */
  52.         /* Diese Routine sollte mit nahezu jedem Drucker gehen! */
  53.         /* wenn man BITS_PER_CHAR (bpc) kennt! */
  54.     
  55.         for(  i=0;  i<len  &&  tmp[5+i]==0;  i++  )
  56.             ;
  57.         while(  tmp[len+4]==0  &&  len>i  )
  58.             len--;
  59.         if(  i<len  )
  60.         {
  61.             for(  j=0;  j<i/bpc;  j++  )                Fwrite( th,  1L, " " );            j *= bpc;            len -= j;            tmp[3] = (UBYTE)(len % 256);
  62.             tmp[4] = (UBYTE)(len / 256);
  63.             Fwrite( th, 5, tmp );
  64.             Fwrite( th, len, tmp+j+5 );
  65.         }
  66. #elif COMPRESSION==1
  67.         /* Schneidet nur rechts ab */
  68.         for(  i=len;  i>0  && tmp[i+5]==0;  i--  )
  69.             ;
  70.         len--;
  71.         if(  i>0  )
  72.         {
  73.             len = i;
  74.             tmp[3] = (UBYTE)(len % 256);
  75.             tmp[4] = (UBYTE)(len / 256);
  76.             Fwrite( th, 5L+len, tmp );
  77.         }
  78. #else
  79.         /* Und unkomprimiert! */
  80.         Fwrite( th, 5L+len, tmp );
  81. #endif
  82.     }
  83.     Fwrite( th, 2L, "\015\012" );
  84. }
  85.  
  86. /********************************************************************/
  87. /* Erst Quer (Landscape) */
  88.  
  89. /* Zwischenspeicher für eine Zeile */static UBYTE    tmp1[WEITE+6L];static UBYTE    tmp2[WEITE+6L];static UBYTE    tmp3[WEITE+6L];static LONG    bit_table[]={    0x00800000L,0x00400000L,0x00200000L,0x00100000L,    0x00080000L,0x00040000L,0x00020000L,0x00010000L,    0x00008000L,0x00004000L,0x00002000L,0x00001000L,    0x00000800L,0x00000400L,0x00000200L,0x00000100L,    0x00000080L,0x00000040L,0x00000020L,0x00000010L,    0x00000008L,0x00000004L,0x00000002L,0x00000001L};/* Querdruck in 216, 144, 72 Dpi */WORD    drucke_quer( UBYTE *p, LONG start_x, LONG weite, LONG hoehe, LONG h_dpi, LONG v_dpi, WORD th, WORD flag )
  90. {    LONG    max_spalte, max_zeile, zeile, lz;    LONG    len, bytes_per_row, offset, i, j, k;    UBYTE    t;
  91.     for(  i=6;  i>0  &&  v_dpi>dpi_modus[i]*11/10;  i-=2  )
  92.         ;
  93.     t = dpi_modus[i+1];
  94.     v_dpi = dpi_modus[i];
  95.  
  96.     for(  i=6;  i>0  &&  h_dpi>dpi_vmodus[i]*11/10;  i-=2  )
  97.         ;
  98.     h_dpi = dpi_vmodus[i];
  99.     bytes_per_row = dpi_vmodus[i+1];
  100.  
  101.         /* Ab hier wird es ernst */    if(  hoehe>(WEITE*h_dpi)/MAX_DPI  )        max_spalte = (WEITE*h_dpi)/MAX_DPI;
  102.     else        max_spalte = (hoehe*h_dpi)/MAX_DPI;
  103.         /* Diverse Variablen initialisieren */    zeile = 0;    max_zeile = weite-start_x;    if(  HOEHE>0    &&    (max_zeile*v_dpi)/MAX_DPI>HOEHE  )
  104.         max_zeile = ((HOEHE-start_x)*v_dpi)/MAX_DPI;
  105.     weite = (weite+15L)/16L;    weite *= 2;        /* Reset + LQ-Mode */
  106.     if(  flag&1  )        Fwrite( th, 8L, INIT );    /* Endlich drucken */    max_zeile--;    while(    max_zeile>0  &&  flag&2  )    {        for(  lz=0;  ist_next_leer( p+lz, weite, hoehe )  &&  lz*8<max_zeile;  lz++  )            ;        if(     lz>0    )        {    /* Leerzeilen überspringen */            zeile += lz*8;            p += lz;
  107.             if(  zeile>max_zeile  )
  108.                 lz = max_zeile-(zeile-lz*8);
  109.             lz = lz*8*3/bytes_per_row;             while(  lz>0  )            {                if(  lz>255  )                    V_STEP[3] = 255;                else                    V_STEP[3] = lz;                Fwrite( th, 4L, V_STEP );                lz -= 255;            }        }        if(  zeile>=max_zeile  )            break;        len = max_spalte;        if(  max_spalte<(WEITE*h_dpi)/MAX_DPI  )            offset = (WEITE*h_dpi)/MAX_DPI-max_spalte;        else            offset = 0;        tmp1[0] = '\033';        tmp1[1] = '*';        tmp1[2] = t;        switch(  (int)bytes_per_row  )        {            case 1:    for(  lz=0;  lz<len;  lz++  )                                tmp1[4L+offset+len-lz] = p[lz*weite];                            memset( tmp1+5, 0, offset );                            write_compressed( th, tmp1, len+offset, (BITS_PER_CHAR*v_dpi)/MAX_DPI );                            p += 1;                        break;            case 2:    memset(  tmp1+5, 0, offset+len );                            memcpy(  tmp2, tmp1, 5+offset+len );                            for(  lz=0;  lz<len;  lz++  )                            {                                i = 256L*p[lz*weite]+p[lz*weite+1];                                if(  i==0L  )                                    continue;                                for(  j=8,k=0;  k<8;  k++  )                                {                                    if(  (i&bit_table[j++])!=0L  )                                        tmp1[4L+offset+len-lz] |= bit_table[16+k];                                    if(  (i&bit_table[j++])!=0L  )                                        tmp2[4L+offset+len-lz] |= bit_table[16+k];                                }                            }                            /* Komprimiert schreiben */                            write_compressed( th, tmp1, len+offset, (BITS_PER_CHAR*v_dpi)/MAX_DPI );                            write_compressed( th, tmp2, len+offset, (BITS_PER_CHAR*v_dpi)/MAX_DPI );                            p += 2;                        break;            case 3:    memset(  tmp1+5, 0, offset+len );                            memcpy(  tmp2, tmp1, 5+offset+len );                            memcpy(  tmp3, tmp1, 5+offset+len );                            for(  lz=0;  lz<len;  lz++  )                            {                                i = p[lz*weite]*65536L+p[lz*weite+1]*256L+p[lz*weite+2];                                if(  i==0  )                                    continue;                                for(  j=k=0;  k<8;  k++  )                                {                                    if(  (i&bit_table[j++])!=0  )                                        tmp1[4L+offset+len-lz] |= bit_table[16+k];                                    if(  (i&bit_table[j++])!=0  )                                        tmp2[4L+offset+len-lz] |= bit_table[16+k];                                    if(  (i&bit_table[j++])!=0  )                                        tmp3[4L+offset+len-lz] |= bit_table[16+k];                                }                            }                            write_compressed( th, tmp1, len+offset, (BITS_PER_CHAR*v_dpi)/MAX_DPI );                            write_compressed( th, tmp2, len+offset, (BITS_PER_CHAR*v_dpi)/MAX_DPI );                            write_compressed( th, tmp3, len+offset, (BITS_PER_CHAR*v_dpi)/MAX_DPI );                            p += 3;                        break;        }        V_STEP[3] = 24-bytes_per_row;        Fwrite( th, 4L, V_STEP );        zeile += bytes_per_row*8;    }    /* Ende Seite */    if(  flag&4  )
  110.         Fwrite( th, 2L, " \014" );
  111.  
  112.     return 0;}/* 17.1.93 */
  113. /********************************************************************/
  114. /* dann Hochkant (Portrait) */
  115.  
  116. WORD    drucke( UBYTE *p, LONG start_y, LONG weite, LONG hoehe, LONG h_dpi, LONG v_dpi, WORD th, WORD flag, WORD quer, UBYTE *option )
  117. {
  118.     LONG    modus, v_modus;
  119.     LONG    max_spalte, zeile, lz, links, linker_rand, rechts;
  120.     LONG    h_len, len, i;
  121.  
  122.     (void)option;    /* ignorieren */
  123.  
  124.     if(  th<-2  )
  125.         th = (WORD)Fopen( "PRN:", FO_WRITE );
  126.  
  127.     if(  quer>0  )
  128.         return drucke_quer( p, start_y, weite, hoehe, h_dpi, v_dpi, th, flag );
  129.  
  130.         /* Auflösung feststellen */
  131.     for(  i=4;  i>0  &&  h_dpi>dpi_modus[i];  i-=2  )
  132.         ;
  133.     modus = dpi_modus[i+1];
  134.     h_dpi = dpi_modus[i];
  135.  
  136.     for(  i=6;  i>0  &&  v_dpi>dpi_vmodus[i]*11/10;  i-=2  )
  137.         ;
  138.     v_dpi = dpi_vmodus[i];
  139.     v_modus = dpi_vmodus[i+1];
  140.  
  141.         /* Ab hier wird es ernst */
  142.     if(  weite<WEITE*h_dpi/MAX_DPI  )
  143.         max_spalte = (weite+7)/8;
  144.     else
  145.         max_spalte = (WEITE*h_dpi)/(8*MAX_DPI);
  146.  
  147.     weite = (weite+15L)/16L;
  148.     weite *= 2;
  149.     if(  flag&1  )
  150.         Fwrite( th, 8L, INIT ); /* Reset + Elite-Dichte + Zeilenabstand 1/216 */
  151.  
  152.     /* Linken Rand festlegen */
  153.     for(  lz=0;  ist_next_leer( p+lz, weite, hoehe )  &&   lz<max_spalte;  lz++  )
  154.         ;
  155.     linker_rand = lz;
  156.  
  157.     lz = links = 0;
  158.     zeile = start_y;
  159.     hoehe += start_y;
  160.  
  161.     /* Endlich drucken */
  162.     while(  flag&2  )
  163.      {
  164.          /* Leerzeilen überspringen */
  165.          for(  lz=0;  ist_leerzeile( p, max_spalte )  &&  zeile<hoehe;  lz++, zeile++  )
  166.              p += weite;
  167.  
  168.         lz = links+(lz+lz+lz)/v_modus;
  169.         while(  lz>0  )
  170.         {
  171.             if(  lz>255  )
  172.                 V_STEP[3] = 255;
  173.             else
  174.                 V_STEP[3] = lz;
  175.             Fwrite( th, 4L, V_STEP );
  176.             lz -= 255;
  177.         }
  178.         if(  zeile>=hoehe  )
  179.             break;
  180.  
  181.             /* Ränder feststellen */
  182.          for(  rechts=max_spalte-1;  ist_next_leer( p+rechts, weite, v_modus*8 )  &&  rechts>linker_rand;  rechts--  )
  183.              ;
  184.          rechts++;
  185.         /* Leerzeichen am linken Rand */
  186.         for(  links=linker_rand;  ist_next_leer( p+links, weite, v_modus*8 )  &&   links<rechts;  links++  )
  187.             ;
  188.         /*  gleichen Anfang festlegen */
  189.         tmp1[0] = 27;
  190.         tmp1[1] = '*';
  191.         tmp1[2] = modus;
  192.         h_len = links*8;
  193.         len = 8*rechts;
  194.         if(  h_len>0  )
  195.             memset( tmp1+5, 0, h_len );
  196.         tmp1[3] = (UBYTE)(len % 256);
  197.         tmp1[4] = (UBYTE)(len / 256);
  198.  
  199.         /* 24 Zeilen (3x Druckkopfhöhe an den Drucker! */
  200.         /* Oder auch weniger bei geringerer Auflösung */
  201.         for(  lz=0;  lz<v_modus;  lz++  )
  202.         {
  203.             block_it( tmp1+5+h_len, p+links, (WORD)(rechts-links), weite*v_modus, 1 );
  204.             p += weite;
  205.             /* Letzte Zeile gesondert behandeln */
  206.             if(  zeile+v_modus*8+lz>=hoehe  )
  207.             {
  208.                 int    bit, byte, and_it;
  209.  
  210.                 bit = (int)((zeile+v_modus*8+lz - hoehe)/v_modus);
  211.                 and_it = (0x00FF<<(bit&7));
  212.                 for(  byte=0;  byte<len-h_len;  byte++  )
  213.                     tmp1[5L+h_len+byte] &= and_it;
  214.             }
  215.             write_compressed( th, tmp1, len, (h_dpi*BITS_PER_CHAR)/MAX_DPI );
  216.       }
  217.         p += weite*v_modus*7L;
  218.         links = 24-v_modus;
  219.         if(  zeile+(8*v_modus)>=hoehe  )
  220.             links = hoehe-zeile-v_modus;
  221.         zeile += (8*v_modus);
  222.  }
  223.  
  224.         /* Ende Seite */
  225.   if(  (flag&4)  )
  226.   {
  227.       if(  2!=Fwrite( th, 2L, " \014" )  )
  228.           /* Platz reichte nicht aus */
  229.             return -1;
  230.   }
  231.     return 0;
  232. }
  233. /* 17.1.93 */
  234.  
  235.